;s10-3
assume cs:code
data segment
    db 10 dup(0)       
data ends

code segment
    start:   
        mov ax,12666
        mov bx,data
        mov ds,bx   ;获取数据段
        mov si,0    ;字符偏移量
        call dtoc
    
        ;字符串参数
        mov dh, 8           ;屏幕的行数
        mov dl, 3           ;所在行的列数
        mov cl, 2           ;颜色属性（此处应是二进制数0000 0010）
        call show_str

        mov ax, 4c00H
        int 21H
    ;---------------
    ;将数字转为字符串
    ;---------------
    dtoc:
        push ax
        push dx
        push cx
        push si ;数据入栈保护

        mov si,0     ;记录有多少个字符
        mov bx,10    ;固定除数

   rem:
        mov dx,0     ;16位除法，先将存储余数的变量置零
        div bx      ;ax/bx=>12666/10 
        mov cx,ax    ;将商ax填充到cx 判断商为零
        jcxz last    ;跳出，数字循环完毕

        ;循环继续
        add dx,30H   ;获取十进制数码对应的ASII码
        push dx      ;存储余数
        inc si       ;在栈中有多少个数据 解决题5
        jmp short rem ;继续读取字符串

    ;处理边界值 最后一次商为零，也需要压栈
    last: 
        add dx,30H  ;字符0的ASCII 是30H
        push dx ;边界值为零
        inc si  

        mov cx,si        ;loop 循环读取存储的字符数据  关键点
        mov si,0         ;数据偏移地址

    s:
        pop ds:[si] ;将asii写入数据段
        inc si
        loop s
    exit:
        pop si ;保护数据出栈
        pop cx
        pop dx
        pop ax
        ret
    ;---------------
    ;屏幕指定位置显示字符串
    ;---------------
    show_str: 
        push dx
        push cx
        push si ;数据入栈保护

        mov ax,0B800H ;在汇编源程序中，数据不能以字母开头，所以要在前面加0。
        mov es,ax     ;显示缓冲区的段地址

        ;计算dl * 2 
        mov ax,0
        mov al,2
        mul dl
        mov bx,ax ;把结果放到dl

        ; 计算 dh * 160 结果在ax中
        mov ax,0   ;（ax）= 0，防止高位不为零  
        mov al,160 ;0a0H
        mul dh
        add bx,ax  ;获取最终否偏移量

        mov di,0   ;di作为字符的偏移零
        mov al,cl  ; 将属性放到al中，因为后边的程序会用到cx
    read:
        mov cl,ds:[si]
        mov ch,0             ;cx中 ch固定为零，关键在于cl的变化是否为零 
        jcxz ok              ;跳出，字符串操作完毕
        mov es:[bx+di+0],cl  ;对字符串业务操作 写入字符
        mov es:[bx+di+1],al  ; 写入属性
        inc si               ;下一个字符串
        add di,2        
        jmp short read       ;继续读取字符串
    ok:
        pop si 
        pop cx
        pop si
        ret

code ends
end start